(function ( exports ) {

    //region NodeCollection

    function NodeCollection () {
        Array.call(this);
    }

    COSA.Util.deriveOverride(Array, NodeCollection, {
        itemTag: '',
        deserialize: function ( node ) {
            var items = node.nodes(this.itemTag),
                _this = this;

            items.forEach( function ( item ) {
                _this.push((_this.getItemInstance()).deserialize(item));
            });

            return this;
        },
        getItemInstance: function () {}
    });

    //endregion NodeCollection

    //region LocalizedLabelCollection

    function LocalizedLabelCollection () {
        NodeCollection.call(this);
    }

    COSA.Util.deriveOverride(NodeCollection, LocalizedLabelCollection, {
        itemTag: 'LocalizedLabel',
        getItemInstance: function () {
            return new COSA.LocalizedLabel();
        }
    });

    //endregion LocalizedLabelCollection

    //region OptionsCollection

    function OptionsCollection () {
        NodeCollection.call(this);
    }

    COSA.Util.deriveOverride(NodeCollection, OptionsCollection, {
        itemTag: 'OptionMetadata',
        getItemInstance: function () {
            return new COSA.OptionMetadata();
        }
    });

    //endregion OptionsCollection

    //region PrivilegesMetadataCollection

    function PrivilegesMetadataCollection () {
        NodeCollection.call(this);
    }

    COSA.Util.deriveOverride(NodeCollection, PrivilegesMetadataCollection, {
        itemTag:'SecurityPrivilegeMetadata',
        getItemInstance: function () {
            return new COSA.SecurityPrivilegeMetadata();
        }
    });

    //endregion PrivilegesMetadataCollection

    //region ManyToManyRelationshipCollection

    function ManyToManyRelationshipCollection () {
        NodeCollection.call(this);
    }

    COSA.Util.deriveOverride(NodeCollection, ManyToManyRelationshipCollection, {
        itemTag:'ManyToManyRelationshipMetadata',
        getItemInstance: function () {
            return new COSA.ManyToManyRelationshipMetadata();
        }
    });

    //endregion ManyToManyRelationshipCollection

    //region OneToManyRelationshipCollection

    function OneToManyRelationshipCollection () {
        NodeCollection.call(this);
    }

    COSA.Util.deriveOverride(NodeCollection, OneToManyRelationshipCollection, {
        itemTag:'OneToManyRelationshipMetadata',
        getItemInstance: function () {
            return new COSA.OneToManyRelationshipMetadata();
        }
    });

    //endregion OneToManyRelationshipCollection

    //region ManyToOneRelationshipCollection

    function ManyToOneRelationshipCollection () {
        OneToManyRelationshipCollection.call(this);
    }

    COSA.Util.deriveOverride(OneToManyRelationshipCollection, ManyToOneRelationshipCollection, {
        itemTag: 'ManyToOneRelationshipCollection'
    });

    //endregion ManyToOneRelationshipCollection

    //region EntityMetadataCollection

    function EntityMetadataCollection () {
        NodeCollection.call(this);
    }

    COSA.Util.deriveOverride(NodeCollection, EntityMetadataCollection, {
        itemTag: 'EntityMetadata',
        getItemInstance: function () {
            return new COSA.EntityMetadata();
        }
    });

    //endregion EntityMetadataCollection

    //region RolePrivilegeCollection

    function RolePrivilegeCollection() {
        NodeCollection.call(this);
    }

    COSA.Util.deriveOverride(NodeCollection, RolePrivilegeCollection, {
        itemTag:'RolePrivilege',
        getItemInstance: function () {
            return new COSA.RolePrivilege();
        }
    });

    //endregion RolePrivilegeCollection

    exports.LocalizedLabelCollection = LocalizedLabelCollection;
    exports.OptionsCollection = OptionsCollection;
    exports.PrivilegesMetadataCollection = PrivilegesMetadataCollection;
    exports.ManyToManyRelationshipCollection = ManyToManyRelationshipCollection;
    exports.OneToManyRelationshipCollection = OneToManyRelationshipCollection;
    exports.ManyToOneRelationshipCollection = ManyToOneRelationshipCollection;
    exports.EntityMetadataCollection = EntityMetadataCollection;
    exports.RolePrivilegeCollection = RolePrivilegeCollection;

})(COSA);
